package com.tjsoft.demo.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

public class BeanUtils extends org.apache.commons.beanutils.BeanUtils {
	/**
	 * 循环向上转型,获取对象的DeclaredField.
	 * @throws NoSuchFieldException 如果没有该Field时抛出.
	 */
	public static Field getDeclaredField(Object object, String propertyName) throws NoSuchFieldException{
		return getDeclaredField(object.getClass(), propertyName);
	}

    /**
     * 循环向上转型,获取对象的DeclaredField.
     * @throws NoSuchFieldException 如果没有该Field时抛出.
     */
    @SuppressWarnings("unchecked")
	public static Field getDeclaredField(Class clazz, String propertyName) throws NoSuchFieldException{
        for (Class superClass = clazz; superClass != Object.class; superClass = superClass.getSuperclass()) {
            try {
                return superClass.getDeclaredField(propertyName);
            } catch (NoSuchFieldException e) {
                // Field不在当前类定义,继续向上转型
            }
        }
        throw new NoSuchFieldException("No such field: " + clazz.getName() + '.' + propertyName);
    }
	/**
	 * 暴力获取对象变量值,忽略private,protected修饰符的限制.
	 * @throws NoSuchFieldException 如果没有该Field时抛出.
	 */
	public static Object forceGetProperty(Object object, String propertyName) throws NoSuchFieldException {
		Field field = getDeclaredField(object, propertyName);

		boolean accessible = field.isAccessible();
		field.setAccessible(true);

		Object result = null;
		try {
			result = field.get(object);
		} catch (IllegalAccessException e) {
            e.printStackTrace();
		}
		field.setAccessible(accessible);
		return result;
	}
	/**
	 * 暴力设置对象变量值,忽略private,protected修饰符的限制.
	 * @throws NoSuchFieldException 如果没有该Field时抛出.
	 */
	public static void forceSetProperty(Object object, String propertyName,Object value) throws NoSuchFieldException {
		try {
			Field field = getDeclaredField(object, propertyName);
			boolean accessible = field.isAccessible();
			field.setAccessible(true);
			field.set(object, value);
			field.setAccessible(accessible);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}

	}
	 /**
     * 将源对象中的属性值拷贝至目标对象.
     * @param destObj   目标对象.
     * @param origObj   源对象.
     */
    public static void copyProperties(Object destObj, Object origObj) {
        try{
            org.apache.commons.beanutils.BeanUtils.copyProperties(destObj,origObj);
        }catch(IllegalAccessException e){
            e.printStackTrace();
        }catch(InvocationTargetException e){
            e.printStackTrace();
        }
    }

}
